/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.webos.java.base;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.webos.java.root.Log;
import org.webos.java.base.Session;
import org.webos.java.base.SessionManager;

/**
 *
 * @author Kostya
 */
public class NetworkManager {

    public static JSONObject getOkObject(){
        try {
            JSONObject object = new JSONObject();
            object.putOpt("type", "response");
            return object;
        } catch (Throwable t) {
            Log.error(null, "Exception thrown: " + t.getMessage());
            t.printStackTrace();
        }
        return null;
    }

    public static JSONObject getErrorObject(int errorCode, String errorDesc){
        try {
            JSONObject object = new JSONObject();
            object.putOpt("type", "error");
            object.put("errorCode", errorCode);
            object.put("errorDescription", errorDesc);
            return object;
        } catch (Throwable t) {
            Log.error(null, "Exception thrown: " + t.getMessage());
            t.printStackTrace();
        }
        return null;
    }

    public static void acceptConnection(String aConnection, HttpServletRequest request, HttpServletResponse response){
        StringBuffer sb = new StringBuffer();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
            try {
                String data = null;
                while((data = reader.readLine())!=null){
                    sb.append(data+"\n");
                }
            } catch (Throwable tt) {
                Log.error(null, "Exception thrown: " + tt.getMessage());
                tt.printStackTrace();
            }
//            Log.debug(null, "Read json from "+sb.toString());
            JSONObject object = null;
            try {
                object = new JSONObject(sb.toString());
            } catch (JSONException jSONException) {
                object = new JSONObject();
            }
            JSONObject responseObject = new JSONObject();
            if("session".equals(aConnection)){
                final Session session = SessionManager.createSession(
                        object.optString("login", ""), object.optString("password", ""));
                if(session==null){
                    responseObject = getErrorObject(2, "You have provided invalid username and/or password");
                }else{
                    session.setDesktop(object.optString("session_type", "DESKTOP").equals("DESKTOP"));
                    session.setOnline(true, true);
                    responseObject = getOkObject();
//                    Log.debug(null, "login: "+object.optString("login"));
                    responseObject.putOpt("token", session.getSessionKey());
                    //Announce all already running applications, frames, workspaces
                    JSONObject apps = new JSONObject();
                    JSONArray arr = new JSONArray();
                    for (int i = 0; i < session.applications.size(); i++) {
                        Application app = session.applications.get(i);
                        if(!(app instanceof CoreApplication)){
                            ApplicationType at = app.getClass().getAnnotation(ApplicationType.class);
                            if(at!=null){
                                JSONObject obj = new JSONObject();
                                obj.put("name", app.getName());
                                obj.put("icon", at.icon());
                                obj.put("code", app.getCode());
                                arr.put(obj);
                            }
                        }

                    }
                    apps.put("apps", arr);
                    session.resetMessages();
                    session.announceApplication(CoreApplication.class);
                    session.getCoreApplication().sendMessage("applicationList", apps);
//                    session.announceApplications();
                }
            }
            if("link".equals(aConnection)){
                String sessionKey = object.optString("token");
//                Log.debug(null, "Establishing link with session "+sessionKey);
                Session session = SessionManager.getSession(sessionKey);
                if(session!=null){
//                    Log.debug(null, "Session is ok, ts = "+request.getParameter("ts"));
                    session.createLink(response);
                    return;
                }else{
                    responseObject = getErrorObject(1, "Invalid session");
                }
            }

            if("message".equals(aConnection)){
                String sessionKey = object.optString("token");
//                Log.debug(null, "Establishing link with session "+sessionKey);
                Session session = SessionManager.getSession(sessionKey);
                if(session!=null){
//                    Log.debug(null, "Session is ok, ts = "+request.getParameter("ts"));
                    session.processMessage(object, response);
                    return;
                }else{
                    responseObject.putOpt("type", "nope");
                }
            }

            //Write response
            sendJSON(response, responseObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void sendJSON(HttpServletResponse response, Object object){
        try {
            response.setContentType("text/html");
            OutputStream os = response.getOutputStream();
    //        Log.debug(null, "Sending "+object);
            os.write(object.toString().getBytes("utf-8"));
            os.close();
            response.flushBuffer();
        } catch (Throwable t) {
            Log.error(null, "Exception thrown: " + t.getMessage());
            t.printStackTrace();
        }
    }
}
